#include "abstractstorage.h"
#include "abstractcontainer.h"
#include "defines.h"

#include <QXmlStreamWriter>
#include <QVariant>
#include <QtDebug>

AbstractStorage::AbstractStorage(const QString &name) : QObject(0)
{
    setObjectName(name);
    initProperties();
}

AbstractStorage::AbstractStorage(AbstractStorage &stor)
{
    initProperties();
    copyDynamicPoperties(&stor);
    setObjectName(stor.objectName());
    QList<AbstractContainer*> *containers = stor.containers();
    for(int i=0;i<containers->size();i++)
    {
        AbstractContainer *cont = containers->at(i);
        m_containers.append( new AbstractContainer(cont) );
    }

}

AbstractStorage::AbstractStorage(AbstractStorage *stor)
{
    initProperties();
    copyDynamicPoperties(stor);
    setObjectName(stor->objectName());
    QList<AbstractContainer*> *containers = stor->containers();
    for(int i=0;i<containers->size();i++)
    {
        AbstractContainer *cont = containers->at(i);
        m_containers.append( new AbstractContainer(cont) );
    }
}

AbstractStorage::~AbstractStorage()
{
    for( int i =0; i < m_containers.size(); i++)
    {
        AbstractContainer *container = m_containers[i];
        delete container;
    }
}

AbstractStorage * AbstractStorage::crateStorage(AbstractStorage::Type id)
{
    AbstractStorage *res = 0;
    switch(id)
    {
    case database:
        res = 0;//new DatabaseStorage();
        break;
    case table:
        res = 0;//new TableStorage();
        break;
    }
    res->initProperties();
    return res;
}

void AbstractStorage::copyDynamicPoperties(const QObject *source)
{
    if(source==0)
        return;

    QList<QByteArray> props = source->dynamicPropertyNames();
    for(int i = 0; i < props.size(); i++)
    {
        this->setProperty(props.at(i),source->property(props.at(i)));
    }
}

void AbstractStorage::writeDynamicPropsToXml(QXmlStreamWriter *pXml)
{
    QList<QByteArray> props = this->dynamicPropertyNames();
    for( int i = 0; i < props.size(); i++ )
    {
        //pXml->writeTextElement(props.at(i),this->property(props.at(i)).toString());
        pXml->writeAttribute(props.at(i),this->property(props.at(i)).toString());
    }
}

void AbstractStorage::readDynamicPropsFromXml(QXmlStreamReader *pXml)
{
    QXmlStreamAttributes attr = pXml->attributes();
    for(int i = 0; i < attr.size(); i++)
    {
        setProperty( attr.at(i).name().toString().toUtf8(), attr.at(i).value().toString() );
    }
}

bool AbstractStorage::readFromXml(QXmlStreamReader *pXml)
{

    while( !pXml->isStartElement() && !pXml->atEnd())
        pXml->readNext();

    if(pXml->atEnd())
        return false;
		
    QString name = pXml->name().toString();
    setObjectName(name);
    readDynamicPropsFromXml(pXml);

    while( !(pXml->name() == name && pXml->isEndElement()) )
    {
        pXml->readNext();
        if(pXml->isStartElement())
        {
            AbstractContainer* container = appendContainer(pXml->name().toString());
            container->readFromXml(pXml);
        }
    }
    return !pXml->hasError();
}

bool AbstractStorage::writeToXml(QXmlStreamWriter *pXml)
{
    pXml->writeStartElement(objectName());
    writeDynamicPropsToXml(pXml);
    for( int i = 0; i < m_containers.size(); i++ )
    {
        m_containers[i]->writeToXml(pXml);
    }
    pXml->writeEndElement();
    return true;
}

AbstractContainer * AbstractStorage::appendContainer(const QString &name)
{
    AbstractContainer *container = new AbstractContainer(name);
    m_containers.append(container);
    return container;
}

AbstractContainer * AbstractStorage::containerByName(const QString &name)
{
    AbstractContainer *res = 0;
    for( int i = 0; i < m_containers.size(); i++ )
    {
        if( m_containers.at(i)->name().compare( name )==0 )
        {
            res = m_containers.at(i);
            break;
        }
    }
    if(res == 0)
        res = appendContainer(name);
    return res;
}

void AbstractStorage::initProperties()
{
    if( objectName().compare( XML_TABLE ) == 0 )
    {
        setProperty(PROP_TABLENAME, "");
        setProperty(PROP_TABLEDESCIPTION, "");
    }
    else if ( objectName().compare( XML_COLUMN) == 0)
    {
        setProperty(PROP_COLUMNNAME, "");
        setProperty(PROP_COLUMNLENTH, "");
        setProperty(PROP_COLUMNTYPE, "0");
        setProperty(PROP_ISPRIMARYKEY, false);
        setProperty(PROP_DEFAULTVALUE, NULLSTRING);
    }
}

